#include <iostream>

using namespace std;

void _const()
{
    // top-level const and bottom-level const
    const int i = 0;
    const int v2 = 0;
    int v1 = v2;
    int *p1 = &v1, &r1 = v1;
    const int *p2 = &v2, *const p3 = &i, &r2 = v2;

    r1 = v2;
    // p1 = p2;
    p2 = p1;
    // p1 = p3;
    p2 = p3;
}

void _type()
{
#include <typeinfo>

    double a = 1;
    double &b = a;
    cout << "double\t a's type:" << typeid(a).name() << endl;
    cout << "ref\t b's type:" << typeid(b).name() << endl;
}

int main()
{
    // point and reference
    int i = 5, j = 10;
    int *p = &i;
    cout << p << " " << *p << endl; // 0x16da62e1c  5
    p = &j;
    cout << p << " " << *p << endl; // 0x16da62e18  10
    *p = 20;
    cout << p << " " << *p << endl; // 0x16da62e18  20
    j = 30;
    cout << p << " " << *p << endl; // 0x16da62e18  30

    // judge point
    int ii = 0;
    int *p1 = nullptr;
    int *pp = &ii;
    if (p1)
        cout << "p1 passed." << endl;
    if (pp) // true
        cout << "pp passed." << endl;
    if (*pp)
        cout << "ii passed." << endl;

    // init with const
    // int i = -1, &r = 0;    // wrong
    const int c = -1, &r = c; // ok
    int *const p2 = &i;       // p2 is const

    const int k = 0;
    // int *p1 = &k; wrong
    _type();
}